package com.hibernate.sessionFactory ;

import java.util.List;
import java.util.Set;

import org.hibernate.Cache;
import org.hibernate.CacheMode;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.hibernate.stat.SessionStatistics;
import org.hibernate.stat.Statistics;
import org.junit.Test;

import com.hibernate.domain.Classes;
import com.hibernate.domain.Student;
import com.hibernate.utils.HibernateUtils;

/**
 * 二级缓存SessionFactory测试类
 * @author LC
 *
 */
public class SessionFactoryTest extends HibernateUtils{
	
	/**
	 * session.get()方法不仅要把对象放入到一级缓存，而且放入到二级缓存
	 */
	@Test
	public void testGet() {
		//打开一个session
		Session session = sessionFactory.openSession() ;
		Classes classes = (Classes)session.get(Classes.class, 1L) ;
		session.close() ;	//关闭当前一级缓存
		
		//重新开启一个session
		session = sessionFactory.openSession();
		Classes classes2 = (Classes)session.get(Classes.class, 1L) ;	//没有发出sql语句
		session.close() ;
	}
	
	/**
	 * session.save()方法不进二级缓存
	 */
	@Test
	public void testSave() {
		Session session = sessionFactory.openSession() ;
		Transaction transaction = session.beginTransaction() ;
		Student student = new Student("策策","测试二级缓存") ;
		session.save(student) ;
		transaction.commit() ;
		session.close() ;	//关闭当前一级缓存
		//统计二级缓存中实体的个数，结果为0，说明session.save方法不进二级缓存
		System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
	}
	
	/**
	 *session.update()方法不进二级缓存 
	 */
	@Test
	public void testUpdate() {
		Session session = sessionFactory.getCurrentSession() ;
		Transaction transaction = session.beginTransaction() ;
		Student student = new Student() ;
		student.setSid(5L) ;
		student.setDescription("111") ;
		session.update(student) ;
		transaction.commit() ; //事务提交，关闭当前一级缓存
		//统计二级缓存中实体的个数，结果为0，说明session.update方法不进二级缓存
		System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
	}
	
	/**
	 * createQuery(hql).list方法能把一个对象放入到二级缓存中，但是不利用二级缓存获取对象
	 */
	@Test
	public void testQuery() {
		Session session = sessionFactory.openSession() ;
		List<Student> students = session.createQuery("from Student").list() ;	
		//统计二级缓存中实体的个数，结果为5，说明session.createQuery方法将提取出来的对象放入到了二级缓存
		System.out.println(sessionFactory.getStatistics().getEntityLoadCount());	
		session.close() ;	//关闭当前session
		
		session = sessionFactory.openSession() ;	//重新打开一个session
		students = session.createQuery("from Student").list() ;	//发出了sql语句，说明并没有从二级缓存中直接获取刚才查询出来的对象
		for (Student student : students) {
			System.out.println(student);
		}
		session.close() ;
	}
	
	/**
	 * ehcache能把数据缓存到磁盘上
	 * @throws Exception 
	 */
	@Test
	public void testObjectOverToDisk() throws Exception {
		Session session = sessionFactory.openSession() ;
		session.createQuery("from Student").list() ; //取出Student表中的所有数据，而在ehcache中指定内存中只能缓存3个student对象，超过3个时将保存到磁盘指定目录
		System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
		session.close() ;
		Thread.sleep(1000L) ;
	}
	
	/**
	 * 二级缓存的集合缓存
	 * 		加载cid为1的班级的所有学生
	 */
	@Test
	public void testCollectionCache() {
		Session session = sessionFactory.openSession() ;
		Classes classes = (Classes)session.get(Classes.class, 1L) ;
		Set<Student> students = classes.getStudents() ;
		for (Student student : students) {
			System.out.println(student);;
		}
		System.out.println(sessionFactory.getStatistics().getCollectionLoadCount()); //统计二级缓存中集合的个数，为1，说明上边查询到的集合数据放入到了二级缓存中
		session.close() ;
	}
	
	@Test
	public void testSecondLevelCache() {
		Session session = sessionFactory.openSession() ;
		CacheMode cacheMode = session.getCacheMode() ; //得到以及缓存对象
		SessionStatistics statistics = session.getStatistics() ; //得到一级缓存统计对象
		Cache cache = sessionFactory.getCache() ; //得到二级缓存对象
		Statistics statistics2 = sessionFactory.getStatistics() ; //得到二级缓存统计对象
	}
	
}
